<template>
  <div class="app-container">
    <div>
      <el-form
        :model="queryParams"
        ref="queryForm"
        size="small"
        :inline="true"
        v-show="showSearch"
        label-width="68px"
      >
        <!-- <el-form-item prop="input">
          <el-input placeholder="请输入" v-model="input" style="width: 500px" @keyup.enter.native="inventoryQuery">
            <el-select v-model="select" slot="prepend" placeholder="请选择" class="select-input">
              <el-option label="Item name" value="1"></el-option>
              <el-option label="GTIN" value="2"></el-option>
              <el-option label="SKU" value="3"></el-option>
              <el-option label="Item ID" value="4"></el-option>
              <el-option label="Brand" value="5"></el-option>
            </el-select>
          </el-input>
        </el-form-item> -->
        <el-form-item label="备货编号" prop="inspector">
          <el-input
            v-model="queryParams.stockNumber"
            placeholder="请输入备货编号"
            clearable
            @keyup.enter.native="handleStockQuery"
          />
        </el-form-item>
        <el-form-item label="sku" prop="sku">
          <el-input
            v-model="queryParams.searchSku"
            placeholder="请输入sku"
            clearable
            @keyup.enter.native="handleStockQuery"
          />
        </el-form-item>
        <el-form-item label="备货状态" prop="inspectionStatus">
          <el-select
            v-model="queryParams.status"
            placeholder="请选择备货状态"
            clearable
          >
            <el-option
              v-for="dict in dict.type.walmart_stock_plan_status"
              :key="dict.value"
              :label="dict.label"
              :value="dict.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="发货方式" prop="inspectionStatus">
          <el-select
            v-model="queryParams.shippingMethod"
            placeholder="请选择发货方式"
            clearable
          >
            <el-option
              v-for="dict in freightMethodOptions"
              :key="dict.id"
              :label="dict.mannerName"
              :value="dict.id"
            />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="handleStockQuery"
            >搜索</el-button
          >
          <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
            >重置</el-button
          >
        </el-form-item>
      </el-form>
      <el-row :gutter="10" class="mb8">
        <el-col :span="1.5">
          <el-button
            type="primary"
            plain
            icon="el-icon-plus"
            size="mini"
            @click="handleAdd"
            v-hasPermi="['depot:stock:add']"
            >新增</el-button
          >
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="success"
            plain
            icon="el-icon-edit"
            size="mini"
            :disabled="single"
            @click="handleUpdate"
            v-hasPermi="['depot:stock:edit']"
            >修改</el-button
          >
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="danger"
            plain
            icon="el-icon-delete"
            size="mini"
            :disabled="multiple"
            @click="handleDelete"
            v-hasPermi="['depot:stock:remove']"
            >删除</el-button
          >
        </el-col>
        <el-col :span="1.5">
          <el-button
            type="info"
            plain
            size="mini"
            icon="el-icon-s-promotion"
            :disabled="multiple"
            @click="handleShipping"
            v-hasPermi="['depot:stock:shipping']"
            >发货</el-button
          >
        </el-col>
      </el-row>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </div>

    <el-table
      v-loading="loading"
      :data="stockList"
      @selection-change="handleSelectionChange"
      style="width: 100%; overflow-x: auto"
    >
      <el-table-column type="selection" min-width="10" align="center" />
      <el-table-column type="expand">
        <template slot-scope="scope">
          <el-table
            :data="scope.row.planList"
            style="width: 100%"
            v-if="scope.row.planList && scope.row.planList.length > 0"
          >
            <el-table-column type="expand">
              <template slot-scope="subScope">
                <el-table
                  :data="
                    getProcessedShipmentData(subScope.row.shipmentsProductList)
                  "
                  style="width: 100%"
                  v-if="
                    subScope.row.shipmentsProductList &&
                    subScope.row.shipmentsProductList.length > 0
                  "
                  :span-method="subTableSpanMethod"
                >
                  <el-table-column
                    label="图片"
                    prop="imgName"
                    align="center"
                    min-width="100"
                  >
                    <template slot-scope="scope">
                      <div class="image-container">
                        <image-preview
                          v-for="(image, index) in scope.row.imgName"
                          :key="index"
                          :src="image"
                          :width="50"
                          :height="50"
                          class="image-item"
                        />
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="品名"
                    align="center"
                    prop="name"
                    min-width="300"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.name || "-" }}
                    </template>
                  </el-table-column>
                  <!-- <el-table-column label="SKU" align="center" prop="sku" min-width="150">
                    <template slot-scope="productScope">
                      {{ productScope.row.sku || '-' }}
                    </template>
                  </el-table-column> -->
                  <el-table-column
                    label="SKU / 属性 / 清单"
                    align="center"
                    prop="sku"
                    min-width="200"
                  >
                    <template slot-scope="productScope">
                      <div style="text-align: left">
                        <div>
                          <strong>{{ productScope.row.sku || "-" }}</strong>
                        </div>

                        <div
                          v-if="productScope.row.attribute"
                          style="margin-top: 4px"
                        >
                          <div
                            style="
                              display: inline-block;
                              margin-right: 4px;
                              margin-bottom: 2px;
                            "
                            v-for="(
                              attrId, index
                            ) in productScope.row.attribute.split(',')"
                            :key="index"
                          >
                            <dict-tag
                              :options="dict.type.sys_product_attribute"
                              :value="attrId.trim()"
                            />
                          </div>
                        </div>

                        <div
                          v-if="productScope.row.packingList"
                          style="margin-top: 4px"
                        >
                          <el-popover
                            placement="right"
                            width="300"
                            trigger="click"
                          >
                            <div
                              style="
                                max-height: 400px;
                                overflow-y: auto;
                                white-space: pre-wrap;
                              "
                            >
                              {{ productScope.row.packingList }}
                            </div>

                            <el-link
                              type="primary"
                              :underline="false"
                              slot="reference"
                            >
                              查看包装清单 <i class="el-icon-document"></i>
                            </el-link>
                          </el-popover>
                        </div>
                      </div>
                    </template>
                  </el-table-column>

                  <el-table-column
                    label="价格(￥)"
                    align="center"
                    prop="price"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.price || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="GTIN"
                    align="center"
                    prop="gtin"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.gtin || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="已发数量"
                    align="center"
                    prop="sentSize"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.sentSize || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="未发数量"
                    align="center"
                    prop="operSize"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.operSize || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="计划数量"
                    align="center"
                    prop="planSize"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.planSize || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="发货数量"
                    align="center"
                    prop="planCount"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.planCount || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="运费"
                    align="center"
                    prop="freight"
                    min-width="150"
                    v-if="checkRole(['admin', 'w', 'K'])"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.freight || "-" }}
                    </template>
                  </el-table-column>
                  <!-- 第一个表格列优化 -->
                  <el-table-column
                    label="采购单个成本组成信息"
                    align="center"
                    prop="purchasingCost"
                    min-width="180"
                  >
                    <template slot-scope="productScope">
                      <div
                        v-if="productScope.row.publicPurchasingInfoBuilder"
                        style="
                          white-space: normal;
                          font-size: 13px;
                          line-height: 1.6;
                        "
                      >
                        <div style="font-weight: bold; margin-bottom: 4px">
                          {{
                            getTitle(
                              productScope.row.publicPurchasingInfoBuilder
                            )
                          }}
                        </div>
                        <div
                          v-for="line in getDetails(
                            productScope.row.publicPurchasingInfoBuilder
                          )"
                          :key="line"
                        >
                          {{ line }}
                        </div>
                      </div>
                      <span v-else>-</span>
                    </template>
                  </el-table-column>

                  <!-- 第二个表格列优化 -->
                  <el-table-column
                    label="采购总成本"
                    align="center"
                    prop="purchasingCost"
                    min-width="180"
                    v-if="checkRole(['admin', 'w', 'K'])"
                  >
                    <template slot-scope="productScope">
                      <div
                        style="
                          display: flex;
                          align-items: center;
                          justify-content: center;
                        "
                      >
                        <span>{{
                          productScope.row.purchasingCost || "-"
                        }}</span>

                        <el-popover
                          trigger="click"
                          placement="top"
                          width="400"
                          v-if="
                            productScope.row.purchasingInfo &&
                            getDetails(productScope.row.purchasingInfo).length >
                              0
                          "
                        >
                          <div
                            style="
                              white-space: normal;
                              font-size: 13px;
                              line-height: 1.6;
                            "
                          >
                            <div style="font-weight: bold; margin-bottom: 4px">
                              {{ getTitle(productScope.row.purchasingInfo) }}
                            </div>
                            <div
                              v-for="line in getDetails(
                                productScope.row.purchasingInfo
                              )"
                              :key="line"
                            >
                              {{ line }}
                            </div>
                          </div>

                          <i
                            slot="reference"
                            class="el-icon-document"
                            style="
                              margin-left: 8px;
                              color: #409eff;
                              cursor: pointer;
                            "
                          ></i>
                        </el-popover>
                      </div>
                    </template>
                  </el-table-column>

                  <el-table-column
                    label="收货状态"
                    align="center"
                    prop="receiptStatus"
                    min-width="105"
                  >
                    <template slot-scope="scope">
                      <div v-if="scope.row.receiptStatus">
                        <!-- 假设传入的是逗号分隔的多个状态值 -->
                        <div
                          v-for="status in scope.row.receiptStatus.split(',')"
                          :key="status"
                        >
                          <!-- 使用 dict-tag 显示每个状态的标签 -->
                          <dict-tag
                            :options="dict.type.walmart_shipments_status"
                            :value="status.trim()"
                          />
                        </div>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column align="center" min-width="150">
                    <!-- 自定义表头 -->
                    <template slot="header">
                      <span>
                        单个头程
                        <el-tooltip
                          effect="dark"
                          content="头程=国际运费/发货数量"
                          placement="top"
                        >
                          <i
                            class="el-icon-info"
                            style="margin-left: 5px; cursor: pointer"
                          ></i>
                        </el-tooltip>
                      </span>
                    </template>
                    <!-- 原有单元格内容保持不变 -->
                    <template slot-scope="productScope">
                      <span>
                        {{
                          productScope.row.freight !== undefined &&
                          productScope.row.freight !== null &&
                          productScope.row.planCount !== undefined &&
                          productScope.row.planCount !== null &&
                          productScope.row.planCount !== 0
                            ? (
                                productScope.row.freight /
                                productScope.row.planCount
                              ).toFixed(2)
                            : "-"
                        }}
                      </span>
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="WFS收货数量"
                    align="center"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{
                        productScope.row.receivedQuantity != null
                          ? productScope.row.receivedQuantity
                          : "-"
                      }}
                    </template>
                  </el-table-column>

                  <!-- 差异数量 -->
                  <el-table-column
                    label="WFS差异数量"
                    align="center"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      <template
                        v-if="
                          productScope.row.receivedQuantity != null &&
                          productScope.row.planCount != null
                        "
                      >
                        <span
                          v-if="
                            productScope.row.receivedQuantity -
                              productScope.row.planCount >
                            0
                          "
                          class="positive"
                        >
                          +{{
                            productScope.row.receivedQuantity -
                            productScope.row.planCount
                          }}
                        </span>
                        <span
                          v-else-if="
                            productScope.row.receivedQuantity -
                              productScope.row.planCount <
                            0
                          "
                          class="negative"
                        >
                          {{
                            productScope.row.receivedQuantity -
                            productScope.row.planCount
                          }}
                        </span>
                        <span v-else>
                          {{
                            productScope.row.receivedQuantity -
                            productScope.row.planCount
                          }}
                        </span>
                      </template>
                      <template v-else>-</template>
                    </template>
                  </el-table-column>

                  <!-- 成本损失(￥) -->
                  <el-table-column
                    label="WFS成本损失(￥)"
                    align="center"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      <template
                        v-if="
                          productScope.row.receivedQuantity != null &&
                          productScope.row.planCount != null &&
                          productScope.row.costPrice != null
                        "
                      >
                        <template
                          v-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              productScope.row.costPrice >
                            0
                          "
                        >
                          <span class="positive">
                            +{{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                productScope.row.costPrice
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template
                          v-else-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              productScope.row.costPrice <
                            0
                          "
                        >
                          <span class="negative">
                            {{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                productScope.row.costPrice
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template v-else>
                          {{
                            (
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                              productScope.row.costPrice
                            ).toFixed(2)
                          }}
                        </template>
                      </template>
                      <template v-else>-</template>
                    </template>
                  </el-table-column>

                  <!-- 头程损失(￥) -->
                  <el-table-column
                    label="WFS头程损失(￥)"
                    align="center"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      <template
                        v-if="
                          productScope.row.receivedQuantity != null &&
                          productScope.row.planCount != null &&
                          productScope.row.freight != null &&
                          productScope.row.planCount !== 0
                        "
                      >
                        <template
                          v-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              (productScope.row.freight /
                                productScope.row.planCount) >
                            0
                          "
                        >
                          <span class="positive">
                            +{{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                (productScope.row.freight /
                                  productScope.row.planCount)
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template
                          v-else-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              (productScope.row.freight /
                                productScope.row.planCount) <
                            0
                          "
                        >
                          <span class="negative">
                            {{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                (productScope.row.freight /
                                  productScope.row.planCount)
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template v-else>
                          {{
                            (
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                              (productScope.row.freight /
                                productScope.row.planCount)
                            ).toFixed(2)
                          }}
                        </template>
                      </template>
                      <template v-else>-</template>
                    </template>
                  </el-table-column>

                  <!-- 合计损失(￥) -->
                  <el-table-column
                    label="WFS合计损失(￥)"
                    align="center"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      <template
                        v-if="
                          productScope.row.receivedQuantity != null &&
                          productScope.row.planCount != null &&
                          productScope.row.costPrice != null &&
                          productScope.row.freight != null &&
                          productScope.row.planCount !== 0
                        "
                      >
                        <template
                          v-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              productScope.row.costPrice +
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                                (productScope.row.freight /
                                  productScope.row.planCount) >
                            0
                          "
                        >
                          <span class="positive">
                            +{{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                  productScope.row.costPrice +
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                  (productScope.row.freight /
                                    productScope.row.planCount)
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template
                          v-else-if="
                            (productScope.row.receivedQuantity -
                              productScope.row.planCount) *
                              productScope.row.costPrice +
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                                (productScope.row.freight /
                                  productScope.row.planCount) <
                            0
                          "
                        >
                          <span class="negative">
                            {{
                              (
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                  productScope.row.costPrice +
                                (productScope.row.receivedQuantity -
                                  productScope.row.planCount) *
                                  (productScope.row.freight /
                                    productScope.row.planCount)
                              ).toFixed(2)
                            }}
                          </span>
                        </template>
                        <template v-else>
                          {{
                            (
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                                productScope.row.costPrice +
                              (productScope.row.receivedQuantity -
                                productScope.row.planCount) *
                                (productScope.row.freight /
                                  productScope.row.planCount)
                            ).toFixed(2)
                          }}
                        </template>
                      </template>
                      <template v-else>-</template>
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="金额(￥)"
                    align="center"
                    prop="amount"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.amount || "-" }}
                    </template>
                  </el-table-column>
                  <el-table-column
                    label="备注"
                    align="center"
                    prop="productRemarks"
                    min-width="150"
                  >
                    <template slot-scope="productScope">
                      {{ productScope.row.productRemarks || "-" }}
                    </template>
                  </el-table-column>
                </el-table>
              </template>
            </el-table-column>
            <el-table-column label="计划编号" align="center" prop="planNumber">
              <template slot-scope="planScope">
                {{ planScope.row.planNumber || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="计划名称" align="center" prop="planName">
              <template slot-scope="planScope">
                {{ planScope.row.planName || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="发货日期" align="center" prop="shipTime">
              <template slot-scope="planScope">
                {{ planScope.row.shipTime || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="发往店铺" align="center" prop="shopName">
              <template slot-scope="planScope">
                {{ planScope.row.shopName || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="货运方式" align="center" prop="mannerName">
              <template slot-scope="planScope">
                {{ planScope.row.mannerName || "-" }}
              </template>
            </el-table-column>
            <el-table-column label="制单人" align="center" prop="createBy">
              <template slot-scope="planScope">
                {{ planScope.row.createBy || "-" }}
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>

      <el-table-column
        label="备货编号"
        align="center"
        prop="stockNumber"
        min-width="80"
      >
        <template slot-scope="scope">
          {{ scope.row.stockNumber || "-" }}
        </template>
      </el-table-column>
      <el-table-column
        label="备货仓库"
        align="center"
        prop="warehouseName"
        min-width="55"
      >
        <template slot-scope="scope">
          {{ scope.row.warehouseName || "-" }}
        </template>
      </el-table-column>
      <el-table-column
        label="发货方式"
        align="center"
        prop="mannerName"
        min-width="55"
      >
        <template slot-scope="scope">
          {{ scope.row.mannerName || "-" }}
        </template>
      </el-table-column>
      <el-table-column
        label="物流信息"
        align="center"
        prop="companyName"
        min-width="120"
      >
        <template slot-scope="scope">
          <div class="logistics-info">
            <div>
              <span class="logistics-label">物流公司:</span>
              <span
                class="logistics-company-link"
                @click="handleOpenLogisticsDialog(scope.row)"
              >
                {{ scope.row.companyName || "-" }}
              </span>
            </div>
            <div style="margin-top: 5px">
              <span class="logistics-label">快递单号:</span>
              <span>{{ scope.row.trackingNumber || "-" }}</span>
              <el-button
                type="text"
                icon="el-icon-edit"
                @click="handleEditTrackingNumber(scope.row)"
                style="padding: 0 0 0 5px"
              ></el-button>
            </div>
          </div>
        </template>
      </el-table-column>

      <!-- 新增：体积计算模式列 -->
      <el-table-column
        label="计算模式"
        align="center"
        prop="volumeMode"
        min-width="55"
      >
        <template slot-scope="scope">
          <span
            @click="handleOpenVolumeModeDialog(scope.row)"
            class="volume-mode-link"
          >
            {{
              scope.row.volumeMode === 1
                ? "按重量(KG)"
                : scope.row.volumeMode === 2
                ? "按体积(m³)"
                : "-"
            }}
          </span>
        </template>
      </el-table-column>
      <el-table-column
        label="发货日期"
        align="center"
        prop="shipmentDate"
        min-width="55"
      >
        <template slot-scope="scope">
          {{ scope.row.shipmentDate || "-" }}
        </template>
      </el-table-column>
      <el-table-column label="备注" align="center" prop="remark" min-width="55">
        <template slot-scope="scope">
          {{ scope.row.remark || "-" }}
        </template>
      </el-table-column>
      <el-table-column
        label="发货状态"
        align="center"
        prop="status"
        min-width="55"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.walmart_stock_plan_status"
            :value="scope.row.status"
          />
        </template>
      </el-table-column>
      <el-table-column
        label="收货状态"
        align="center"
        prop="receiptStatus"
        min-width="55"
      >
        <template slot-scope="scope">
          <div v-if="scope.row.receiptStatus">
            <!-- 假设传入的是逗号分隔的多个状态值 -->
            <div
              v-for="status in scope.row.receiptStatus.split(',')"
              :key="status"
            >
              <!-- 使用 dict-tag 显示每个状态的标签 -->
              <dict-tag
                :options="dict.type.walmart_shipments_status"
                :value="status.trim()"
              />
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="发货数" align="center" min-width="55">
        <template slot-scope="scope">
          {{ totalSentSizeForRow[scope.$index] }}
        </template>
      </el-table-column>
      <!-- 在导入方案按钮前增加的查看按钮 -->
      <el-table-column label="查看方案" align="center" min-width="55">
        <template slot-scope="scope">
          <el-button type="info" size="mini" @click="openViewDialog(scope.row)"
            >查看</el-button
          >
        </template>
      </el-table-column>
      <!-- 新增的“导入方案”列 -->
      <el-table-column label="导入方案" align="center" min-width="55">
        <template slot-scope="scope">
          <!-- 点击按钮时，调用方法，并将当前行信息传递过去 -->
          <el-button
            type="primary"
            size="mini"
            @click="openImportDialog(scope.row)"
            v-hasPermi="['depot:stock:import']"
          >
            添加装箱清单
          </el-button>
          <!-- 新增的导入运费按钮 -->
          <el-button
            type="warning"
            size="mini"
            @click="openImportFreightDialog(scope.row)"
            v-hasPermi="['depot:stock:importFreight']"
          >
            导入运费
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加仓库备货 -->
    <el-dialog
      :title="title"
      :visible.sync="open"
      width="700px"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-row :gutter="20">
          <el-col :span="10">
            <el-form-item label="销售计划:" prop="planNumber">
              <el-select
                v-model="form.planNumber"
                multiple
                placeholder="请选择销售计划"
                style="width: 100%"
              >
                <el-option
                  v-for="plan in selectedParentPlanNumbers"
                  :key="plan"
                  :label="plan"
                  :value="plan"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="10">
            <el-button round @click="handleSalesPlan">选择销售计划</el-button>
          </el-col>
        </el-row>

        <!-- 新增仓库选择 -->
        <el-row :gutter="20">
          <el-col :span="10">
            <el-form-item label="仓库:" prop="warehouse">
              <el-select
                v-model="form.warehouse"
                placeholder="请选择仓库"
                style="width: 100%"
              >
                <el-option
                  v-for="warehouse in warehouseOptions"
                  :key="warehouse.id"
                  :label="warehouse.label"
                  :value="warehouse.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <!-- 新增的备注输入框 -->
        <el-row :gutter="20">
          <el-col :span="20">
            <el-form-item label="备注" prop="remark">
              <el-input
                v-model="form.remark"
                type="textarea"
                placeholder="请输入内容"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>

      <!-- 底部按钮区域 -->
      <div slot="footer" class="dialog-footer">
        <el-button @click="openCancel">取消</el-button>
        <el-button type="primary" @click="openConfirmSelection">确定</el-button>
      </div>
    </el-dialog>

    <!-- 选择销售计划 -->
    <el-dialog
      :title="titleSalesPlan"
      :visible.sync="openSalesPlan"
      width="90%"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-form
        :model="queryParamPlan"
        ref="queryForm"
        size="small"
        :inline="true"
        v-show="showSearch"
        label-width="68px"
      >
        <el-form-item label="计划编号" prop="planNumber">
          <el-input
            v-model="queryParamPlan.planNumber"
            placeholder="请输入计划编号"
            clearable
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="计划名称" prop="planName">
          <el-input
            v-model="queryParamPlan.planName"
            placeholder="请输入计划名称"
            clearable
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>

        <el-form-item>
          <el-button
            type="primary"
            icon="el-icon-search"
            size="mini"
            @click="handleQuery"
            >搜索</el-button
          >
          <el-button icon="el-icon-refresh" size="mini" @click="saleResetQuery"
            >重置</el-button
          >
        </el-form-item>
      </el-form>

      <el-table
        v-loading="loading"
        :data="planList"
        ref="table"
        @expand-change="handleRowExpand"
      >
        <!-- <el-table-column type="selection" width="55" align="center" /> -->
        <el-table-column align="center" width="20" type="expand">
          <template slot-scope="scope">
            <el-table
              :data="getProcessedShipmentData(scope.row.shipmentsProductList)"
              :ref="'childTable-' + scope.row.planNumber"
              @selection-change="
                (val) => handleChildSelectionChange(scope.row, val)
              "
              row-key="id"
              :span-method="childSpanMethod"
            >
              <el-table-column
                type="selection"
                width="55"
                align="center"
                :reserve-selection="true"
                :selectable="(row, index) => row.operSize !== 0"
              />
              <el-table-column
                label="图片"
                prop="imgName"
                align="center"
                min-width="100"
              >
                <template slot-scope="scope">
                  <div class="image-container">
                    <image-preview
                      v-for="(image, index) in scope.row.imgName"
                      :key="index"
                      :src="image"
                      :width="50"
                      :height="50"
                      class="image-item"
                    />
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="品名" prop="name" align="center">
              </el-table-column>
              <el-table-column label="SKU" align="center" prop="sku">
              </el-table-column>
              <el-table-column label="GTIN" align="center" prop="gtin">
              </el-table-column>
              <el-table-column
                label="可用量(可销售库存)"
                prop="availableQuantity"
                align="center"
              >
              </el-table-column>
              <el-table-column label="价格(￥)" prop="price" align="center">
              </el-table-column>
              <el-table-column label="已发数量" prop="sentSize" align="center">
              </el-table-column>
              <el-table-column label="未发数量" prop="operSize" align="center">
              </el-table-column>
              <el-table-column label="计划数量" prop="planSize" align="center">
              </el-table-column>
              <el-table-column label="金额(￥)" prop="amount" align="center">
              </el-table-column>
              <el-table-column
                label="产品备注"
                prop="productRemarks"
                align="center"
              >
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column
          label="计划编号"
          align="center"
          prop="planNumber"
          width="150px"
        />
        <el-table-column label="计划名称" align="center" prop="planName">
          <template slot-scope="scope">
            <span v-if="scope.row.planName">
              {{ scope.row.planName.slice(0, 10) }}
              <span v-if="scope.row.planName.length > 10">...</span>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="发货日期" align="center" prop="shipTime">
          <template slot-scope="scope">
            <span>{{ parseTime(scope.row.shipTime, "{y}-{m}-{d}") }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="货运方式"
          align="center"
          prop="mannerName"
          width="180px"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.mannerName">
              {{ scope.row.mannerName.slice(0, 10) }}
              <span v-if="scope.row.mannerName.length > 10">...</span>
            </span>
          </template>
        </el-table-column>
        <el-table-column label="发往店铺" align="center" prop="shopName" />
        <el-table-column label="制单人" align="center" prop="nickName" />
        <el-table-column label="备货状态" align="center" prop="shippingStatus">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sales_plan_shipping_status"
              :value="scope.row.shippingStatus"
            />
          </template>
        </el-table-column>
        <el-table-column label="计划状态" align="center" prop="planStatus">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.tb_plan"
              :value="scope.row.planStatus"
            />
          </template>
        </el-table-column>
        <el-table-column
          label="制单日期"
          align="center"
          prop="preparationTime"
          width="135"
        >
          <template slot-scope="scope">
            <span
              >{{ parseTime(scope.row.preparationTime, "{y}-{m}-{d}") }}
              {{ parseTime(scope.row.preparationTime, "{h}:{i}") }}</span
            >
          </template>
        </el-table-column>
        <!-- <el-table-column label="审核人" align="center" prop="approver" />
          <el-table-column label="审核日期" align="center" prop="auditTime">
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.auditTime, "{y}-{m}-{d}") }}</span>
            </template>
          </el-table-column> -->
        <el-table-column
          label="备注"
          align="center"
          prop="remark"
          width="170px"
        >
          <template slot-scope="scope">
            <span v-if="scope.row.remark">
              {{ scope.row.remark.slice(0, 10) }}
              <span v-if="scope.row.remark.length > 10">...</span>
            </span>
          </template>
        </el-table-column>
      </el-table>

      <!-- 弹窗底部按钮 -->
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="confirmSelection">确定</el-button>
        <el-button @click="cancel">取消</el-button>
      </div>
      <pagination
        v-show="totalPlan > 0"
        :total="totalPlan"
        :page.sync="queryParamPlan.pageNum"
        :limit.sync="queryParamPlan.pageSize"
        @pagination="getPlanList"
      />
    </el-dialog>

    <!-- 选择货运方式弹窗 -->
    <el-dialog
      :visible.sync="showMannerDialog"
      title="选择货运方式"
      :close-on-click-modal="false"
      width="500px"
    >
      <el-select v-model="selectedManner" placeholder="请选择货运方式">
        <el-option
          v-for="(manner, index) in mannerOptions"
          :key="index"
          :label="manner.mannerName"
          :value="manner.mannerId"
        />
      </el-select>

      <span slot="footer" class="dialog-footer">
        <el-button @click="mannerCancel">取消</el-button>
        <el-button type="primary" @click="confirmMannerSelection"
          >确定</el-button
        >
      </span>
    </el-dialog>

    <!-- 物流公司选择弹窗 -->
    <el-dialog
      :visible.sync="logisticsDialogVisible"
      title="选择物流公司"
      :close-on-click-modal="false"
      width="300px"
    >
      <el-select
        v-model="selectedLogistics"
        placeholder="请选择物流公司"
        :filterable="false"
      >
        <el-option
          v-for="(item, index) in logisticsOptions"
          :key="index"
          :label="item.companyName"
          :value="item.id"
        />
      </el-select>
      <span slot="footer" class="dialog-footer">
        <el-button @click="logisticsCancel">取消</el-button>
        <el-button type="primary" @click="confirmLogisticsSelection"
          >确定</el-button
        >
      </span>
    </el-dialog>

    <!-- <div style="margin-bottom: 15px;"> -->
    <!-- 下载导入模板按钮 -->
    <!-- <el-button type="primary" icon="el-icon-download" size="mini" @click="downloadTemplate">
          下载导入模板
        </el-button>
      </div> -->

    <!-- 文件上传 -->
    <!-- <el-upload class="upload-demo" ref="excelUpload" :auto-upload="false" :action="'#'"
        :before-upload="beforeUploadExcel" :on-change="handleFileChange" :on-success="handleImportSuccess"
        :on-error="handleImportError" :file-list="fileList" accept=".xls,.xlsx">
        <el-button type="primary" icon="el-icon-upload" size="mini">
          选择文件
        </el-button>
        <div slot="tip" class="el-upload__tip">
          只能上传Excel文件，格式为 .xls 或 .xlsx
        </div>
      </el-upload> -->

    <!-- 导入备货方案弹窗 -->
    <el-dialog
      title="导入备货方案"
      :visible.sync="importDialogVisible"
      width="90%"
      append-to-body
      :close-on-click-modal="false"
    >
      <!-- 表格部分 -->
      <el-table
        :data="tableData"
        border
        style="width: 100%"
        :span-method="tableSpanMethod"
      >
        <!-- 操作列：每一行都有删除按钮，最后一行显示新增按钮 -->
        <el-table-column width="120">
          <template slot-scope="scope">
            <el-button
              type="text"
              icon="el-icon-delete"
              @click="deleteRow(scope.$index)"
              :disabled="importType === 'freight'"
            ></el-button>
            <div
              v-if="scope.$index === tableData.length - 1"
              style="display: inline-block"
            >
              <el-button
                type="text"
                icon="el-icon-plus"
                @click="addRow"
                :disabled="importType === 'freight'"
              ></el-button>
            </div>
          </template>
        </el-table-column>

        <!-- 箱序列 -->
        <el-table-column label="箱序" prop="boxNumber">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.boxNumber"
              placeholder="填写箱序"
              @blur="syncBoxOrder(scope.row)"
              :disabled="importType === 'freight'"
            ></el-input>
          </template>
        </el-table-column>

        <!-- SKU列：使用下拉框，只允许选择，禁止手工输入 -->
        <el-table-column label="SKU" prop="sku">
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.sku"
              placeholder="请选择SKU"
              @change="setDefaultGtinForSingleOption(scope)"
              :disabled="importType === 'freight'"
            >
              <el-option
                v-for="option in skuOptions"
                :key="option"
                :label="option"
                :value="option"
              ></el-option>
            </el-select>
          </template>
        </el-table-column>

        <!-- GTIN列：使用下拉框，只允许选择，禁止手工输入 -->
        <el-table-column label="GTIN" prop="gtin">
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.gtin"
              placeholder="请选择GTIN"
              :disabled="!scope.row.sku || importType === 'freight'"
            >
              <el-option
                v-for="(option, index) in gtinOptions[scope.row.sku]
                  ? gtinOptions[scope.row.sku].gtins
                  : []"
                :key="index"
                :label="option"
                :value="option"
              />
            </el-select>
          </template>
        </el-table-column>

        <!-- 产品尺寸列 -->
        <el-table-column label="产品尺寸" prop="productSize">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.productSize"
              placeholder="填写产品尺寸"
              disabled
            ></el-input>
          </template>
        </el-table-column>

        <!-- 重量列 -->
        <el-table-column label="产品重量" prop="productWeight">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.productWeight"
              placeholder="填写产品重量"
              disabled
            ></el-input>
          </template>
        </el-table-column>

        <!-- 数量列 -->
        <el-table-column label="数量" prop="quantity">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.quantity"
              placeholder="填写数量"
              :disabled="importType === 'freight'"
            ></el-input>
          </template>
        </el-table-column>

        <!-- 尺寸列 -->
        <el-table-column label="尺寸" prop="boxSize">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.boxSize"
              placeholder="填写尺寸"
              @blur="syncMerge('boxSize', scope.row)"
              :disabled="importType === 'freight'"
            ></el-input>
          </template>
        </el-table-column>

        <!-- 重量列 -->
        <el-table-column label="重量" prop="boxWeight">
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.boxWeight"
              placeholder="填写重量"
              @blur="syncMerge('boxWeight', scope.row)"
              :disabled="importType === 'freight'"
            ></el-input>
          </template>
        </el-table-column>

        <!-- 运费列：仅在导入运费时显示 -->
        <el-table-column
          label="运费"
          prop="freight"
          v-if="importType === 'freight'"
        >
          <template slot-scope="scope">
            <el-input
              v-model="scope.row.freight"
              placeholder="填写总金额之后自动计算"
              disabled
            ></el-input>
          </template>
        </el-table-column>

        <el-table-column
          label="单个运费"
          prop="unitFreight"
          v-if="importType === 'freight'"
        >
          <template slot-scope="{ row }">
            <el-input
              v-model="row.unitFreight"
              placeholder="填写总金额之后自动计算"
              disabled
            ></el-input>
          </template>
        </el-table-column>

        <!-- <el-table-column label="运费" prop="freight">
          <template slot-scope="scope">
            <el-input v-model="scope.row.freight" placeholder="填写运费"></el-input>
          </template>
        </el-table-column> -->
      </el-table>

      <!-- 新增金额输入区域 -->
      <el-row style="margin-top: 20px" v-if="importType === 'freight'">
        <el-col :span="6" :offset="0">
          <div style="display: flex; align-items: center">
            <span style="margin-right: 8px">总金额：</span>
            <el-input
              v-model="totalAmount"
              placeholder="请输入总金额"
              @blur="calculateFreight"
              prefix-icon="el-icon-money"
              style="flex: 1"
            ></el-input>
          </div>
        </el-col>
      </el-row>

      <!-- 弹窗底部操作按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="
            importType === 'freight' ? submitImportFreight() : submitImport()
          "
          :loading="loading"
          >确认导入</el-button
        >
      </span>
    </el-dialog>

    <!-- 只读查看导入方案弹窗（带合并单元格效果） -->
    <el-dialog
      title="查看导入方案"
      :visible.sync="viewDialogVisible"
      width="80%"
      append-to-body
      :close-on-click-modal="false"
    >
      <el-table
        :data="viewDialogData"
        border
        style="width: 100%"
        :span-method="viewSpanMethod"
      >
        <!-- 列顺序：箱序、SKU、数量、尺寸、重量、运费 -->
        <el-table-column
          label="箱序"
          prop="boxNumber"
          align="center"
        ></el-table-column>
        <el-table-column
          label="SKU"
          prop="sku"
          align="center"
        ></el-table-column>
        <el-table-column
          label="GTIN"
          prop="gtin"
          align="center"
        ></el-table-column>
        <el-table-column
          label="产品尺寸"
          prop="productSize"
          align="center"
        ></el-table-column>
        <el-table-column
          label="产品重量"
          prop="productWeight"
          align="center"
        ></el-table-column>
        <el-table-column
          label="数量"
          prop="quantity"
          align="center"
        ></el-table-column>
        <el-table-column
          label="尺寸"
          prop="boxSize"
          align="center"
        ></el-table-column>
        <el-table-column
          label="重量"
          prop="boxWeight"
          align="center"
        ></el-table-column>
        <el-table-column
          label="运费"
          prop="freight"
          align="center"
          v-if="checkRole(['admin', 'w', 'K'])"
        ></el-table-column>
        <el-table-column
          label="单个运费"
          prop="unitFreight"
          align="center"
        ></el-table-column>
      </el-table>

      <!-- 底部按钮（只有取消） -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="viewDialogVisible = false">取消</el-button>
      </span>
    </el-dialog>

    <el-dialog
      title="修改物流公司"
      :visible.sync="updatelogisticsDialogVisible"
      width="400px"
      append-to-body
      @close="resetLogisticsForm"
    >
      <el-form ref="logisticsForm" :model="logisticsForm" label-width="0px">
        <el-form-item prop="selectedLogisticsId">
          <el-select
            v-model="logisticsForm.selectedLogisticsId"
            placeholder="请选择物流公司"
            style="width: 100%"
            filterable
          >
            <el-option
              v-for="item in logisticsOptions"
              :key="item.id"
              :label="item.companyName"
              :value="item.id"
            >
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="updatelogisticsDialogVisible = false"
          >取 消</el-button
        >
        <el-button
          type="primary"
          @click="submitLogisticsChange"
          :loading="logisticsSubmitLoading"
          >确 定</el-button
        >
      </div>
    </el-dialog>
    <!-- 体积模式选择弹窗 -->
    <el-dialog
      title="修改体积计算模式"
      :visible.sync="updateVolumeDialogVisible"
      width="350px"
      append-to-body
      @close="resetVolumeForm"
    >
      <el-form ref="volumeForm" :model="volumeForm" label-width="0">
        <el-form-item prop="selectedVolumeMode">
          <el-select
            v-model="volumeForm.selectedVolumeMode"
            placeholder="请选择体积模式"
            style="width: 100%"
            size="mini"
          >
            <el-option label="按重量(KG)" value="1" />
            <el-option label="按体积(m³)" value="2" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="updateVolumeDialogVisible = false">取 消</el-button>
        <el-button
          type="primary"
          @click="submitVolumeModeChange"
          :loading="volumeSubmitLoading"
          >确 定</el-button
        >
      </div>
    </el-dialog>

    <!-- 编辑快递单号弹窗 -->
    <el-dialog
      title="编辑快递单号"
      :visible.sync="trackingNumberDialogVisible"
      width="30%"
    >
      <el-form :model="trackingNumberForm" label-width="80px">
        <el-form-item label="备货编号">
          <span>{{ trackingNumberForm.stockNumber }}</span>
        </el-form-item>
        <el-form-item label="物流公司">
          <span>{{ trackingNumberForm.companyName }}</span>
        </el-form-item>
        <el-form-item label="快递单号" prop="trackingNumber">
          <el-input
            v-model="trackingNumberForm.trackingNumber"
            placeholder="请输入快递单号"
            clearable
            @keyup.enter.native="submitTrackingNumber"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="trackingNumberDialogVisible = false"
          >取 消</el-button
        >
        <el-button type="primary" @click="submitTrackingNumber"
          >确 定</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { StockPlanlistPlan } from "@/api/sale/plan";
import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
import {
  listPlan as stockListPlan,
  addPlan,
  getStockPlan,
  updatePlan,
  delPlan,
  importTemplate,
  importFreight,
  selectSku,
  selectGTIN,
  getImportedPlan,
  shippingPlan,
  updateStockPlanLogistics,
  updateStockPlanVolumeMode,
  updateStockTrackingNumber,
} from "@/api/sale/stockPlan";
import { listFreightMethod } from "@/api/sale/FreightMethod";
import { updateShipmentStockFirstLeg } from "@/api/finance/walmartProfit";
import { getSelectPreWarehouseTreeList } from "@/api/procured/plan";
import { getSelectLogisticsTreeList } from "@/api/depot/company";
// import * as XLSX from 'xlsx';
// import { saveAs } from 'file-saver';
export default {
  dicts: [
    "tb_plan",
    "walmart_stock_plan_status",
    "walmart_shipments_status",
    "sales_plan_shipping_status",
    "sys_product_attribute",
  ],
  data() {
    return {
      // 显示搜索条件
      showSearch: true,
      // 遮罩层
      loading: false,
      //仓库备货所有数据
      stockList: [],
      // 弹出层标题
      title: "",
      titleSalesPlan: "",
      // 是否显示弹出层
      open: false,
      openSalesPlan: false,
      ids: [],
      // 表单参数
      form: {
        stockId: null,
        stockNumber: null,
        shippingMethod: null, // 货运方式
        status: null,
        shipmentDate: null,
        remark: "",
        warehouse: null,
        planNumber: null,
        logisticsCompany: null, // 物流公司
      },
      // 仓库备货查询参数
      queryParams: {
        searchSku: "",
        pageNum: 1,
        pageSize: 10,
      },
      //销售计划参数
      queryParamPlan: {
        pageNum: 1,
        pageSize: 10,
        planName: null,
        planStatus: 1, // 代表已核准的销售计划
        shippingStatus: 2, // 查询不等于2（已发货）的销售计划
        flag: true, //代表销售计划时查询的是合并之后的一对多GTIN数据
      },
      total: 0,
      totalPlan: 0,
      // 销售中心表格数据
      planList: [],
      input: "", // Add this property
      select: null, // Add this property
      selectedPlans: [], // Store selected plans
      single: true, // Example value for single
      multiple: true, // Example value for multiple
      rules: {}, // Define the rules
      selectedRows: [],
      selectedParentPlanNumbers: [], // 用来存储选中的父项 planNumber
      // 控制弹窗的显示
      showMannerDialog: false,
      // 用户选择的货运方式
      selectedManner: null,
      // 选择框中的货运方式数据(包含 mannerId 和 mannerName)
      mannerOptions: [],
      freightMethodOptions: [], // 用于存储搜索栏货运方式相关数据
      isEdit: false, // 标识是编辑还是新增

      importDialogVisible: false, // 控制导入弹窗显示/隐藏
      currentStockRow: null, // 当前操作的备货计划行信息，可用于后续关联
      importType: "plan", // 'plan'：导入备货方案；'freight'：导入运费
      // 初始一行数据，后续点击加号新增空行
      tableData: [
        {
          boxNumber: "",
          sku: "",
          gtin: "",
          quantity: "",
          boxSize: "",
          boxWeight: "",
          freight: "",
          unitFreight: "",
        },
      ],
      // 用于导入备货计划清单中 sku 下拉框选项
      skuOptions: [],
      // 用于导入备货计划清单中 sku 下拉框选项
      gtinOptions: [],
      warehouseOptions: [], // 仓库列表
      // 新增查看弹窗控制变量和数据
      viewDialogVisible: false,
      viewDialogData: [], // 用于展示导入的数据

      // 物流公司选择弹窗数据
      logisticsDialogVisible: false,
      selectedLogistics: null,
      logisticsOptions: [],
      // fileList: [],             // 上传文件列表

      // --- 修改物流公司弹窗所需的新增属性 ---
      updatelogisticsDialogVisible: false, // 控制新弹窗的显示/隐藏
      currentEditingStockPlan: null, // 存储正在编辑的行的备货计划数据
      logisticsForm: {
        // 弹窗的表单数据
        selectedLogisticsId: null, // 选中的物流公司 ID
      },
      logisticsSubmitLoading: false, // 弹窗“确定”按钮的加载状态
      // --- 新增属性结束 ---

      // --- 修改体积计算模式弹窗所需的新增属性 ---
      stockPlans: [], // 表格数据
      // 体积模式弹窗控制
      updateVolumeDialogVisible: false,
      volumeForm: {
        selectedVolumeMode: null, // kg 或 m3
      },
      volumeSubmitLoading: false,
      // --- 新增属性结束 ---
      totalAmount: null, // 总运费
      // 快递单号对话框
      trackingNumberDialogVisible: false,
      trackingNumberForm: {
        stockId: null,
        stockNumber: "",
        companyName: "",
        trackingNumber: "",
      },
    };
  },
  created() {
    listFreightMethod()
      .then((response) => {
        this.freightMethodOptions = response.rows;
      })
      .catch((error) => {
        this.$message.error("获取货运方式数据失败");
      });

    this.getList();
    this.getLogistics();
  },
  computed: {
    totalSentSizeForRow() {
      const result = this.stockList.map((stockItem, index) => {
        const stockSentSize = stockItem.planList.reduce(
          (innerSum, planItem) => {
            const shipmentsSum = planItem.shipmentsProductList.reduce(
              (shipSum, shipment) => {
                return shipSum + (shipment.planCount || 0);
              },
              0
            );
            return innerSum + shipmentsSum;
          },
          0
        );
        return stockSentSize;
      });
      return result;
    },
  },
  methods: {
    checkPermi, // 权限判断函数（1）
    checkRole, // 权限判断函数（2）
    // 采购总成本详细信息展示用到的函数
    getTitle(info) {
      return info.split("\n")[0] || "";
    },
    getDetails(info) {
      return info
        .split("\n")
        .slice(1)
        .filter((line) => line);
    },
    // 添加仓库备货
    handleAdd() {
      this.title = "添加仓库备货";
      this.open = true;
      this.isEdit = false; // 标识为新增
      this.form.remark = ""; // 清空备注
      this.form.planNumber = null; // 清空销售计划编号
      this.form.warehouse = null; // 清空仓库选择
      this.selectedParentPlanNumbers = []; // 清空销售计划下拉框
      this.getPreWarehouse();
      this.getLogistics();
    },
    getPreWarehouse() {
      getSelectPreWarehouseTreeList().then((response) => {
        this.warehouseOptions = response.data;
      });
    },
    // 查询物流公司下拉框列表
    getLogistics() {
      getSelectLogisticsTreeList()
        .then((response) => {
          this.logisticsOptions = response.rows || response.data || [];
        })
        .catch((error) => {
          console.error("获取物流公司列表失败:", error);
          this.$message.error("获取物流公司列表失败");
          this.logisticsOptions = []; // 出错时确保是空数组
        });
    },
    // 修改仓库备货计划
    handleUpdate() {
      const status = this.selectedRows[0].status;
      if (status == 1) {
        this.$message.error("备货计划已经发货，不能进行修改！");
        return;
      }
      this.title = "修改仓库备货";
      this.open = true;
      this.isEdit = true; // 标识为编辑
      this.getPreWarehouse();
      this.getLogistics();
      this.selectedPlans = [];
      getStockPlan(this.ids[0]).then((response) => {
        this.selectedParentPlanNumbers = response.data.planList.map(
          (item) => item.planNumber
        );
        response.data.planList.forEach((plan) => {
          if (
            plan.shipmentsProductList &&
            Array.isArray(plan.shipmentsProductList)
          ) {
            this.selectedPlans = this.selectedPlans.concat(
              plan.shipmentsProductList
            );
          }
        });
        // const { stockId, stockNumber, shippingMethod, status, shipmentDate, remark } = response.data;
        // this.form = { stockId, stockNumber, shippingMethod, status, shipmentDate, remark };
        // this.form.planNumber = this.selectedParentPlanNumbers;
        // this.form.warehouse = response.data.stockWarehouse;
        // 逐个赋值更新 form 中的属性
        // 从 response.data 解构出对应的变量
        const {
          stockId,
          stockNumber,
          shippingMethod,
          status,
          shipmentDate,
          remark,
          stockWarehouse,
          logisticsCompany,
        } = response.data;
        this.form.stockId = stockId;
        this.form.stockNumber = stockNumber;
        this.form.shippingMethod = shippingMethod;
        this.form.logisticsCompany = logisticsCompany;
        this.form.status = status;
        this.form.shipmentDate = shipmentDate;
        this.form.remark = remark;
        this.form.planNumber = this.selectedParentPlanNumbers;
        this.form.warehouse = stockWarehouse;
      });
    },
    async handleSalesPlan() {
      this.titleSalesPlan = "选择销售计划";
      this.openSalesPlan = true;
      this.mannerOptions = [];

      // 获取销售计划列表数据
      await this.getPlanList();
      this.selectedParentPlanNumbers = this.form.planNumber || []; // 恢复已选的父项编号
      this.selectedPlans = this.getSelectedPlansFromParentNumbers(); // 通过父项编号恢复已选的子项
    },
    // 获取已选择的子项
    getSelectedPlansFromParentNumbers() {
      const selectedPlans = [];
      // 遍历所有已选父项的编号
      this.selectedParentPlanNumbers.forEach((planNumber) => {
        const parent = this.planList.find((p) => p.planNumber === planNumber);
        if (parent) {
          // 遍历该父项下的所有子项
          parent.shipmentsProductList.forEach((child) => {
            // 如果该子项已被选中，则添加到 selectedPlans 中
            const isSelected = this.selectedPlans.some(
              (item) =>
                item.productId === child.productId &&
                item.planNumber === planNumber
            );
            if (isSelected) {
              selectedPlans.push(child);
            }
          });
        }
      });
      // console.log(JSON.stringify(selectedPlans, null, 2));
      return selectedPlans;
    },
    /** 查询销售中心列表 */
    getPlanList() {
      this.loading = true; // 开启 loading 状态
      return new Promise((resolve, reject) => {
        StockPlanlistPlan(this.queryParamPlan)
          .then((response) => {
            this.planList = response.rows;
            this.totalPlan = response.total;
            this.loading = false; // 请求完成，关闭 loading 状态
            resolve(); // 数据加载完成，resolve Promise
          })
          .catch((error) => {
            this.loading = false;
            console.error("Error loading plans:", error);
            reject(error); // 如果请求失败，reject Promise
          });
      });
    },
    getList() {
      this.loading = true;
      stockListPlan(this.queryParams).then((response) => {
        this.stockList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    handleStockQuery() {
      this.getList();
    },
    cancel() {
      // 1. 重置表单数据
      this.$refs.form.resetFields(); // 如果你使用了 el-form，可以用 resetFields 来重置表单字段

      // 2. 清空已选择的子项
      this.selectedPlans = [];

      // 3. 清空已选中的父项 planNumber
      this.selectedParentPlanNumbers = [];

      // 4. 清空其他临时数据
      this.selectedManner = null; // 清空选中的货运方式
      this.mannerOptions = []; // 清空货运方式选项

      this.selectedLogistics = null; // 清空物流公司

      // 5. 关闭弹窗
      this.openSalesPlan = false;
      this.showMannerDialog = false;
    },
    openCancel() {
      this.form.planNumber = null;
      this.selectedManner = null;
      this.open = false;
    },
    mannerCancel() {
      this.mannerOptions = [];
      this.selectedManner = null;
      this.selectedLogistics = null; // 清空物流公司
      this.showMannerDialog = false;
    },
    handleSelectionChange(selection) {
      this.ids = selection.map((item) => item.stockId);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
      this.selectedRows = selection;
    },
    openConfirmSelection() {
      if (
        this.form.planNumber.length == 0 ||
        this.selectedParentPlanNumbers.length == 0
      ) {
        this.$message.warning("请选择销售计划！");
        return;
      }
      if (!this.form.warehouse) {
        this.$message.warning("请选择备货仓库！");
        return;
      }
      if (!this.isEdit) {
        const obj = {
          selectedManner: this.selectedManner,
          logisticsCompany: this.selectedLogistics,
          shipmentsProductList: this.selectedPlans,
          warehouse: this.form.warehouse,
          remark: this.form.remark,
          goShop: this.form.goShop,
        };
        console.log(JSON.stringify(obj, null, 2));

        addPlan(obj)
          .then((response) => {
            this.$message.success("添加成功");
            this.open = false;
            this.getList();
          })
          .catch((error) => {
            // 处理失败的响应
            this.$message.error("添加失败");
          });
      } else {
        this.form.selectedPlans = this.selectedPlans; // 选中数据
        if (this.selectedManner) {
          this.form.shippingMethod = this.selectedManner; // 货运方式
        }
        if (this.logisticsCompany) {
          this.form.logisticsCompany = this.selectedLogistics; // 选中的物流公司
        }
        this.form.stockWarehouse = this.form.warehouse;
        this.form.authId = this.form.goShop;
        updatePlan(this.form)
          .then((response) => {
            this.$message.success("修改成功");
            this.open = false;
            this.getList();
          })
          .catch((error) => {
            // 处理失败的响应
            this.$message.error("修改失败");
          });
      }
    },
    handleChildSelectionChange(parentRow, selectedRows) {
      // 获取当前父项的所有子项
      const parentPlanNumber = parentRow.planNumber;

      // 处理取消勾选的项
      // 遍历 selectedPlans，保留当前父项下选中的子项
      this.selectedPlans = this.selectedPlans.filter((item) => {
        // 只保留当前父项下选中的子项
        if (item.planNumber === parentPlanNumber) {
          // 如果该子项不在当前选中的子项中，则移除它
          return selectedRows.some(
            (child) =>
              `${child.planNumber}-${child.id}` ===
              `${item.planNumber}-${item.id}`
          );
        }
        return true; // 保留其他父项的数据
      });
      // 处理选中项
      selectedRows.forEach((child) => {
        const uniqueKey = `${child.planNumber}-${child.id}`;

        // 判断是否已存在相同的组合（planNumber + productId）
        const isExist = this.selectedPlans.some((item) => {
          return `${item.planNumber}-${item.id}` === uniqueKey;
        });

        // 如果不存在相同的组合，才添加该子项
        if (!isExist) {
          this.selectedPlans.push(child);
        }
      });

      // 更新 selectedParentPlanNumbers：如果该父项下没有选中的子项，移除该父项
      if (selectedRows.length === 0) {
        const index = this.selectedParentPlanNumbers.indexOf(
          parentRow.planNumber
        );
        if (index !== -1) {
          this.selectedParentPlanNumbers.splice(index, 1); // 移除父项的 planNumber
        }
      } else {
        // 如果存在选中的子项，添加父项的 planNumber
        if (!this.selectedParentPlanNumbers.includes(parentRow.planNumber)) {
          this.selectedParentPlanNumbers.push(parentRow.planNumber);
        }
      }
    },

    // confirmSelection() {
    //   if (this.selectedPlans.length <= 0) {
    //     this.$message("请选择销售计划产品！");
    //     return;
    //   }
    //   // 直接使用 selectedPlans 获取选中的子项
    //   const selectedItems = this.selectedPlans;  // 选中的子项都已经保存在 selectedPlans 中

    //   // 存储选中的父项的 planNumber 和 mannerName
    //   const selectedParentPlanNumbers = [];
    //   const mannerNames = [];

    //   selectedItems.forEach(item => {
    //     if (!selectedParentPlanNumbers.includes(item.planNumber)) {
    //       selectedParentPlanNumbers.push(item.planNumber);  // 添加父项的 planNumber
    //     }

    //     // 收集每个父项的 mannerName 和 mannerId
    //     const parent = this.planList.find(p => p.planNumber === item.planNumber);
    //     if (parent && !mannerNames.includes(parent.mannerName)) {
    //       mannerNames.push(parent.mannerName);
    //       // 将货运方式的数据存储到 mannerOptions
    //       this.mannerOptions.push({
    //         mannerId: parent.mannerId,
    //         mannerName: parent.mannerName
    //       });
    //     }
    //   });
    //   // 检查选择的父项的 mannerName 是否一致
    //   if (mannerNames.length > 1) {
    //     // 如果有多个不同的 mannerName，则弹出提示框让用户选择统一的货运方式
    //     this.showMannerDialog = true; // 显示弹窗
    //   } else {
    //     // 如果 mannerName 一致，直接进行后续操作
    //     this.form.planNumber = selectedParentPlanNumbers;
    //     this.selectedManner = this.mannerOptions[0].mannerId
    //     this.openLogisticsDialog();
    //   }
    // },

    confirmSelection() {
      this.form.goShop = null;
      if (this.selectedPlans.length <= 0) {
        this.$message("请选择销售计划产品！");
        return;
      }

      // 直接使用 selectedPlans 获取选中的子项
      const selectedItems = this.selectedPlans; // 选中的子项都已经保存在 selectedPlans 中

      // 存储选中的父项的 planNumber 和 mannerName
      const selectedParentPlanNumbers = [];
      const mannerNames = [];

      // 存储goShop的值
      const selectedShops = [];

      selectedItems.forEach((item) => {
        if (!selectedParentPlanNumbers.includes(item.planNumber)) {
          selectedParentPlanNumbers.push(item.planNumber); // 添加父项的 planNumber
        }

        // 收集每个父项的 mannerName 和 mannerId
        const parent = this.planList.find(
          (p) => p.planNumber === item.planNumber
        );
        if (parent && !mannerNames.includes(parent.mannerName)) {
          mannerNames.push(parent.mannerName);
          // 将货运方式的数据存储到 mannerOptions
          this.mannerOptions.push({
            mannerId: parent.mannerId,
            mannerName: parent.mannerName,
          });
        }

        // 收集goShop
        if (parent && !selectedShops.includes(parent.goShop)) {
          selectedShops.push(parent.goShop);
        }
      });

      // 检查选择的父项的 goShop 是否一致
      if (selectedShops.length > 1) {
        this.$message("只能选择同一个店铺下的产品！");
        return;
      }

      // 如果 goShop 一致，保存店铺ID到 form 中
      if (selectedShops.length === 1) {
        this.form.goShop = selectedShops[0]; // 将店铺ID添加到 form 中
      }

      // 检查选择的父项的 mannerName 是否一致
      if (mannerNames.length > 1) {
        // 如果有多个不同的 mannerName，则弹出提示框让用户选择统一的货运方式
        this.showMannerDialog = true; // 显示弹窗
      } else {
        // 如果 mannerName 一致，直接进行后续操作
        this.form.planNumber = selectedParentPlanNumbers;
        this.selectedManner = this.mannerOptions[0].mannerId;
        this.openLogisticsDialog();
      }
    },

    confirmMannerSelection() {
      // 用户选择了货运方式后，执行相关操作
      // 执行后续操作，例如将统一的货运方式设置为选中的方式
      if (!this.selectedParentPlanNumbers) {
        this.$message.warning("请选择货运方式！");
        return;
      }
      this.form.planNumber = this.selectedParentPlanNumbers; // 设置选择的父项的 planNumber
      this.openSalesPlan = false; // 关闭弹窗
      this.showMannerDialog = false; // 关闭选择货运方式的弹窗
      this.openLogisticsDialog();
    },

    handleQuery() {
      // Handle search query
      this.getPlanList();
    },
    resetQuery() {
      // Reset search parameters
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
      };
      this.getList();
    },
    saleResetQuery() {
      this.queryParamPlan.planNumber = null;
      this.queryParamPlan.planName = null;
      this.getPlanList();
    },
    handleDelete() {
      const flag = this.selectedRows.some((item) => item.status == 1);
      if (flag) {
        this.$message.error("删除的选项中包含已发货的备货计划禁止删除！");
        return;
      }
      // 弹出确认对话框
      this.$confirm("确定要删除该备货计划吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 用户确认后执行删除操作
          delPlan(this.ids)
            .then((response) => {
              this.$message.success("删除成功");
              this.getList();
            })
            .catch((error) => {
              this.$message.error("删除失败");
            });
        })
        .catch(() => {
          // 用户取消操作后的回调
          this.$message.info("已取消删除");
        });
    },
    // 发货
    handleShipping() {
      const flag = this.selectedRows.some((item) => item.status == 1);
      if (flag) {
        this.$message.error("本次发货的选项中包含已经发货的备货计划！");
        return;
      }
      // 弹出确认对话框
      this.$confirm("确定要进行发货吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 用户确认后执行删除操作
          shippingPlan(this.ids)
            .then((response) => {
              this.$message.success("发货成功");
              this.getList();
            })
            .catch((error) => {
              this.$message.error("发货失败");
            });
        })
        .catch(() => {
          // 用户取消操作后的回调
          this.$message.info("已取消发货");
        });
    },
    handleRowExpand(row, expanded) {
      // 使用 $nextTick 等待 DOM 更新完成
      this.$nextTick(() => {
        const childTableRef = this.$refs["childTable-" + row.planNumber]; // 获取子表格的 ref

        // 确保子表格存在
        if (childTableRef && expanded) {
          const parentPlanNumber = row.planNumber;

          // 找到当前父项下选中的子项
          const selectedItems = this.selectedPlans.filter(
            (item) => item.planNumber === parentPlanNumber
          );

          // 使用 toggleRowSelection 恢复子项的选中状态
          selectedItems.forEach((selectedItem) => {
            const rowData = row.shipmentsProductList.find(
              (item) => item.id === selectedItem.id
            );
            if (rowData) {
              childTableRef.toggleRowSelection(rowData, true); // true 表示选中
            }
          });
        }
      });
    },

    // 打开弹窗
    openImportDialog(row) {
      if (row.status == 1) {
        this.$message.error("备货计划已经发货，禁止添加备货清单！");
        return;
      }
      this.importType = "plan";
      (this.tableData = [
        {
          boxNumber: "",
          sku: "",
          gtin: null,
          quantity: "",
          boxSize: "",
          boxWeight: "",
          productSize: "",
          productWeight: "",
          freight: "",
          unitFreight: "",
        },
      ]),
        (this.currentStockRow = row); // 保存当前行信息，便于导入时知道是哪一个备货计划
      // this.fileList = [];             // 清空已选文件
      this.importDialogVisible = true; // 显示弹窗
      // 查询对应的SKU下拉列表
      selectSku(row.stockId)
        .then((response) => {
          this.skuOptions = response.data;
        })
        .catch((error) => {
          console.log(error);
        });

      // 查询对应的GTIN下拉列表
      selectGTIN(row.stockId)
        .then((response) => {
          this.gtinOptions = response.data;
        })
        .catch((error) => {
          console.log(error);
        });
    },
    // 在选择SKU时调用此方法
    setDefaultGtinForSingleOption(scope) {
      const sku = scope.row.sku;
      const gtinOptions = this.gtinOptions[sku];

      // 如果GTIN选项数量为1且当前未设置GTIN时，自动填充
      if (gtinOptions.gtins.length === 1) {
        scope.row.gtin = gtinOptions.gtins[0]; // 自动填充
      }
      scope.row.productSize = gtinOptions.packageSize;
      scope.row.productWeight = gtinOptions.packageWeight + "KG";
    },
    // 新增 openImportFreightDialog 方法，设置 importType 为 'freight'
    openImportFreightDialog(row) {
      if (
        row.volumeMode == null ||
        !row.volumeMode ||
        row.volumeMode == undefined
      ) {
        this.$message.error("请选择体积计算模式之后再导入运费！");
        return;
      }
      this.importType = "freight";
      this.totalAmount = null; // 清空金额
      this.tableData = [
        {
          boxNumber: "",
          sku: "",
          gtin: null,
          quantity: "",
          boxSize: "",
          boxWeight: "",
          productSize: "",
          productWeight: "",
          freight: "",
          unitFreight: "",
        },
      ];
      this.currentStockRow = row;
      this.importDialogVisible = true;
      // 加载已导入的数据，假设后端返回的数据中包含运费信息
      getImportedPlan(row.stockId)
        .then((response) => {
          this.tableData = response.data.map((item) => ({
            ...item,
            freight: null,
            unitFreight: null,
          }));
        })
        .catch((error) => {
          this.$message.error("加载导入运费数据失败！");
        });
    },
    // 点击加号新增一行数据
    addRow() {
      this.tableData.push({
        boxNumber: "",
        sku: "",
        gtin: null,
        quantity: "",
        boxSize: "",
        boxWeight: "",
        productSize: "",
        productWeight: "",
        freight: "",
        unitFreight: "",
      });
    },
    // 删除指定行（保证至少保留一行，否则清空数据）
    deleteRow(index) {
      if (this.tableData.length > 1) {
        this.tableData.splice(index, 1);
      } else {
        this.$message("至少保留一行数据！");
        this.tableData[0] = {
          boxNumber: "",
          sku: "",
          gtin: null,
          quantity: "",
          boxSize: "",
          boxWeight: "",
          productSize: "",
          productWeight: "",
          freight: "",
          unitFreight: "",
        };
      }
    },

    submitImport() {
      // 遍历所有行进行校验
      for (let i = 0; i < this.tableData.length; i++) {
        const row = this.tableData[i];

        // 先校验不能为空
        if (!row.boxNumber) {
          this.$message.error(`第 ${i + 1} 行的箱序不能为空`);
          return;
        }
        if (!row.quantity) {
          this.$message.error(`第 ${i + 1} 行的数量不能为空`);
          return;
        }
        if (!row.boxWeight) {
          this.$message.error(`第 ${i + 1} 行的重量不能为空`);
          return;
        }

        if (!row.boxSize) {
          this.$message.error(`第 ${i + 1} 行的尺寸不能为空`);
          return;
        }
        // 校验 SKU 不能为空
        if (!row.sku) {
          this.$message.error(`第 ${i + 1} 行的SKU不能为空`);
          return;
        }
        // 校验 GTIN 不能为空
        if (!row.gtin) {
          this.$message.error(`第 ${i + 1} 行的GTIN不能为空`);
          return;
        }
        // 校验数量不能为 0
        if (parseFloat(row.quantity) === 0) {
          this.$message.error(`第 ${i + 1} 行的数量不能为0`);
          return;
        }

        // 校验箱序：允许单个数字或范围格式 (例如 "1-50")
        if (!/^\d+$/.test(row.boxNumber) && !/^\d+-\d+$/.test(row.boxNumber)) {
          this.$message.error(
            `第 ${i + 1} 行的箱序格式必须为单个数字或者范围格式(如1-50)`
          );
          return;
        }

        // 如果是范围格式，确保起始值小于结束值
        if (/^\d+-\d+$/.test(row.boxNumber)) {
          const [start, end] = row.boxNumber.split("-").map(Number);
          if (start >= end) {
            this.$message.error(
              `第 ${i + 1} 行的箱序范围不正确，起始值必须小于结束值`
            );
            return;
          }
        }

        // 校验数量：必须为数字（可以是整数或小数）
        if (!/^\d+(\.\d+)?$/.test(row.quantity)) {
          this.$message.error(`第 ${i + 1} 行的数量必须为数字`);
          return;
        }
        // 校验重量：必须以 KG 为后缀，并且前面为数字（例如 12KG 或 12.5KG）
        if (!/^\d+(\.\d+)?KG$/i.test(row.boxWeight)) {
          this.$message.error(`第 ${i + 1} 行的重量必须以KG为后缀且前面为数字`);
          return;
        }

        // 校验尺寸：必须符合 "数字*数字*数字" 格式
        if (!/^\d+(\.\d+)?\*\d+(\.\d+)?\*\d+(\.\d+)?$/.test(row.boxSize)) {
          this.$message.error(
            `第 ${i + 1} 行的尺寸格式必须为 xx*xx*xx 且为数字`
          );
          return;
        }
      }

      // 校验箱序范围和SKU组合的重复情况
      for (let i = 0; i < this.tableData.length; i++) {
        const currentRow = this.tableData[i];
        const currentBoxNumber = currentRow.boxNumber;
        const currentSku = currentRow.sku;

        for (let j = 0; j < this.tableData.length; j++) {
          // 跳过自身比较
          if (i === j) continue;

          const otherRow = this.tableData[j];
          const otherBoxNumber = otherRow.boxNumber;
          const otherSku = otherRow.sku;

          // 如果SKU不同，则不需要校验箱序重叠
          if (currentSku !== otherSku) continue;

          // 检查箱序是否重叠
          const isOverlapping = this.checkBoxNumberOverlap(
            currentBoxNumber,
            otherBoxNumber
          );
          if (isOverlapping) {
            this.$message.error(
              `箱序 ${currentBoxNumber} 与箱序 ${otherBoxNumber} 存在重叠，并且SKU相同(${currentSku})，请检查`
            );
            return;
          }
        }
      }

      // 校验同一箱序下的 SKU 和 GTIN 组合不能重复
      const groupMap = {};
      this.tableData.forEach((row, index) => {
        // 根据箱序进行分组，假设箱序一定有值
        const key = row.boxNumber;
        if (!groupMap[key]) {
          groupMap[key] = [];
        }
        // 存储需要校验的字段 (sku, gtin) 和原始索引，以备后用
        groupMap[key].push({ sku: row.sku, gtin: row.gtin, index });
      });

      // 遍历每个箱序的分组
      for (const boxNumber in groupMap) {
        const itemsInBox = groupMap[boxNumber]; // 获取当前箱序下的所有项

        // 创建一个表示 "SKU||GTIN" 组合的列表
        // 我们将 sku 和 gtin 组合成一个唯一的字符串来检测重复
        // 注意：如果 sku 或 gtin 可能为 null 或 undefined，需要确保组合方式能正确区分
        const combinationList = itemsInBox.map((item) => {
          // 使用一个不太可能出现在 sku 或 gtin 中的分隔符，如 '||'
          const skuValue =
            item.sku === null || item.sku === undefined ? "NULL_SKU" : item.sku; // 处理 null/undefined
          const gtinValue =
            item.gtin === null || item.gtin === undefined
              ? "NULL_GTIN"
              : item.gtin; // 处理 null/undefined
          return `${skuValue}||${gtinValue}`;
        });

        // 使用 Set 来查找唯一的组合字符串
        const uniqueCombinations = new Set(combinationList);

        // 比较唯一组合的数量和原始列表的数量
        if (uniqueCombinations.size !== combinationList.length) {
          // 如果数量不一致，说明存在重复的 SKU 和 GTIN 组合
          // 你可以选择在这里找出具体是哪个组合重复了，但这通常不是必需的，报告箱序即可
          this.$message.error(
            `箱序为 ${boxNumber} 下存在重复的 SKU 和 GTIN 组合`
          );
          return; // 发现错误后立即停止校验并返回
        }
      }
      // 将当前备货计划的 stockId 添加到每一行数据中
      const stockId = this.currentStockRow.stockId;
      const submitData = this.tableData.map((row) => ({
        ...row,
        stockId,
      }));
      console.log(JSON.stringify(submitData, null, 2));

      this.loading = true;
      importTemplate(submitData)
        .then((res) => {
          this.loading = false;
          this.$message.success("导入成功");
          this.importDialogVisible = false;
          this.getList(); // 刷新数据
        })
        .catch((err) => {
          this.loading = false;
          this.$message.error("导入失败");
          // this.importDialogVisible = false;
        })
        .finally(() => {
          this.totalAmount = null;
        });
    },

    // 新增提交导入运费的函数
    submitImportFreight() {
      // 对运费字段进行校验
      for (let i = 0; i < this.tableData.length; i++) {
        const row = this.tableData[i];
        if (!row.unitFreight) {
          this.$message.error(`第 ${i + 1} 行的运费不能为空`);
          return;
        }
        if (!/^\d+(\.\d+)?$/.test(row.unitFreight)) {
          this.$message.error(`第 ${i + 1} 行的运费必须为数字`);
          return;
        }
      }
      const stockId = this.currentStockRow.stockId;
      const submitData = this.tableData.map((row) => ({ ...row, stockId }));
      this.loading = true;
      // 假设后端提供 importFreight 接口，用于导入运费数据
      importFreight(
        submitData,
        this.totalAmount,
        this.currentStockRow.volumeMode
      )
        .then((res) => {
          this.loading = false;
          this.$message.success("导入运费成功");
          this.importDialogVisible = false;
          this.getList();
          // 调用更新头程费用的方法
          updateShipmentStockFirstLeg(stockId)
            .then((response) => {
              console.log("头程费用更新成功", response);
            })
            .catch((error) => {
              console.error("头程费用更新失败", error);
              this.$message.warning("运费导入成功，但头程费用更新失败");
            });
        })
        .catch((err) => {
          this.loading = false;
          this.$message.error("导入运费失败");
        });
    },
    /**
     * 合并单元格逻辑：
     * 针对箱序、尺寸、重量这三列（由于操作列占第0列，因此箱序在列索引1、尺寸在4、重量在5），
     * 只有当这三个字段都有值且完全相同时，才进行合并。否则直接返回默认。
     */
    tableSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 使用prop属性名来确定要合并的列
      const mergeColumns = ["boxNumber", "boxSize", "boxWeight", "freight"];

      if (!mergeColumns.includes(column.property)) {
        return { rowspan: 1, colspan: 1 };
      }

      const current = this.tableData[rowIndex];
      // 若任一字段为空，则不合并
      if (!current.boxNumber || !current.boxSize || !current.boxWeight) {
        return { rowspan: 1, colspan: 1 };
      }

      // 如果当前行与上一行数据相同，则隐藏当前单元格
      if (rowIndex > 0) {
        const prev = this.tableData[rowIndex - 1];
        if (
          prev.boxNumber === current.boxNumber &&
          prev.boxSize === current.boxSize &&
          prev.boxWeight === current.boxWeight
        ) {
          return { rowspan: 0, colspan: 0 };
        }
      }

      // 否则，统计连续满足条件的行数
      let groupCount = 1;
      for (let i = rowIndex + 1; i < this.tableData.length; i++) {
        const next = this.tableData[i];
        if (
          current.boxNumber === next.boxNumber &&
          current.boxSize === next.boxSize &&
          current.boxWeight === next.boxWeight
        ) {
          groupCount++;
        } else {
          break;
        }
      }

      return { rowspan: groupCount, colspan: 1 };
    },
    /**
     * 当尺寸或重量输入失焦时，同步同一箱序下的该字段数据，
     * 确保合并区域内数据一致，避免因数据不一致而拆分合并效果。
     */
    syncMerge(field, currentRow) {
      const value = currentRow[field];
      this.tableData.forEach((row) => {
        if (row.boxNumber === currentRow.boxNumber) {
          row[field] = value;
        }
      });
    },
    /**
     * 当箱序输入完成后（失焦），如果已存在相同箱序的记录，
     * 同步已填写的尺寸和重量数据到当前行，并重新排序 tableData，
     * 使得相同箱序的行连续，从而达到合并效果。
     */
    syncBoxOrder(changedRow) {
      this.$nextTick(() => {
        if (!changedRow.boxNumber) return;

        // 检查箱序格式
        if (
          !/^\d+$/.test(changedRow.boxNumber) &&
          !/^\d+-\d+$/.test(changedRow.boxNumber)
        ) {
          this.$message.error(`箱序格式不正确，应为单个数字或范围格式(如1-50)`);
          changedRow.boxNumber = "";
          return;
        }

        // 如果是范围格式，检查起始值是否小于结束值
        if (/^\d+-\d+$/.test(changedRow.boxNumber)) {
          const [start, end] = changedRow.boxNumber.split("-").map(Number);
          if (start >= end) {
            this.$message.error(`箱序范围不正确，起始值必须小于结束值`);
            changedRow.boxNumber = "";
            return;
          }
        }

        // 如果有SKU，检查与其他行的箱序和SKU组合是否有重叠
        if (changedRow.sku) {
          for (let i = 0; i < this.tableData.length; i++) {
            const otherRow = this.tableData[i];
            // 跳过自身
            if (otherRow === changedRow) continue;
            // 如果SKU不同，则不需要校验
            if (otherRow.sku !== changedRow.sku) continue;

            const isOverlapping = this.checkBoxNumberOverlap(
              changedRow.boxNumber,
              otherRow.boxNumber
            );
            if (isOverlapping) {
              this.$message.error(
                `箱序 ${changedRow.boxNumber} 与箱序 ${otherRow.boxNumber} 存在重叠，并且SKU相同(${changedRow.sku})，请检查`
              );
              changedRow.boxNumber = "";
              return;
            }
          }
        }

        if (!changedRow.boxNumber) return;
        // 找出所有相同箱序的行
        const groupRows = this.tableData.filter(
          (row) => row.boxNumber === changedRow.boxNumber
        );
        // 如果已有记录中有填写了尺寸和重量的作为参考
        const refRow = groupRows.find((row) => row.boxSize && row.boxWeight);
        if (refRow) {
          groupRows.forEach((row) => {
            row.boxSize = refRow.boxSize;
            row.boxWeight = refRow.boxWeight;
          });
        }
        // 重新排序 tableData，使得相同箱序的行连续显示
        this.tableData.sort((a, b) => {
          if (!a.boxNumber) return 1;
          if (!b.boxNumber) return -1;
          // 处理范围格式和单个数字的排序
          const aValue = this.getBoxNumberSortValue(a.boxNumber);
          const bValue = this.getBoxNumberSortValue(b.boxNumber);
          return aValue - bValue;
        });
      });
    },

    /**
     * 检查两个箱序是否重叠
     */
    checkBoxNumberOverlap(boxNum1, boxNum2) {
      // 将两个箱序转换为范围
      let range1 = this.parseBoxNumber(boxNum1);
      let range2 = this.parseBoxNumber(boxNum2);

      // 检查范围是否重叠
      return range1.start <= range2.end && range2.start <= range1.end;
    },

    /**
     * 将箱序转换为范围对象 {start, end}
     */
    parseBoxNumber(boxNumber) {
      // 如果是单个数字
      if (/^\d+$/.test(boxNumber)) {
        const num = parseInt(boxNumber);
        return { start: num, end: num };
      }
      // 如果是范围格式 "1-50"
      else if (/^\d+-\d+$/.test(boxNumber)) {
        const [start, end] = boxNumber.split("-").map(Number);
        return { start, end };
      }
      // 默认返回
      return { start: 0, end: 0 };
    },

    /**
     * 获取箱序的排序值
     */
    getBoxNumberSortValue(boxNumber) {
      const range = this.parseBoxNumber(boxNumber);
      // 使用起始值作为排序依据
      return range.start;
    },
    openViewDialog(row) {
      // row是当前行数据，根据stockId获取已导入的数据
      this.viewDialogVisible = true;

      // 根据当前stockId查询已导入的方案数据（调用后端API）
      this.loading = true;
      getImportedPlan(row.stockId)
        .then((response) => {
          // 假设后端返回的是已导入的数据列表
          this.viewDialogData = response.data;
          this.loading = false;
        })
        .catch((error) => {
          this.loading = false;
          this.$message.error("加载导入数据失败！");
        });
    },
    viewSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 仅对箱序（索引0）、尺寸（索引3）和重量（索引4）列进行合并
      if (![0, 6, 7].includes(columnIndex)) {
        return { rowspan: 1, colspan: 1 };
      }
      const current = this.viewDialogData[rowIndex];
      // 如果任一字段为空，不进行合并
      if (!current.boxNumber || !current.boxSize || !current.boxWeight) {
        return { rowspan: 1, colspan: 1 };
      }
      // 如果当前行与上一行相同，则隐藏当前单元格
      if (rowIndex > 0) {
        const prev = this.viewDialogData[rowIndex - 1];
        if (
          prev.boxNumber === current.boxNumber &&
          prev.boxSize === current.boxSize &&
          prev.boxWeight === current.boxWeight
        ) {
          return { rowspan: 0, colspan: 0 };
        }
      }
      // 统计连续满足条件的行数
      let groupCount = 1;
      for (let i = rowIndex + 1; i < this.viewDialogData.length; i++) {
        const next = this.viewDialogData[i];
        if (
          current.boxNumber === next.boxNumber &&
          current.boxSize === next.boxSize &&
          current.boxWeight === next.boxWeight
        ) {
          groupCount++;
        } else {
          break;
        }
      }
      return { rowspan: groupCount, colspan: 1 };
    },
    // 打开物流公司选择弹窗
    openLogisticsDialog() {
      this.logisticsDialogVisible = true;
    },
    logisticsCancel() {
      this.logisticsDialogVisible = false;
    },
    // 确认物流公司选择后，提交备货计划（调用新增接口）
    confirmLogisticsSelection() {
      if (!this.selectedLogistics) {
        this.$message.warning("请选择物流公司！");
        return;
      }
      this.openSalesPlan = false; // 关闭弹窗
      // 赋值物流公司到表单
      this.form.logisticsCompany = this.selectedLogistics;
      this.logisticsDialogVisible = false;
    },
    /**
     * @description 预处理子表格数据，用于 SKU 合并
     * 1. 按 SKU 排序
     * 2. 计算每个 SKU 分组需要合并的行数 (_span)
     * @param {Array} shipments 原始的产品列表
     * @returns {Array} 处理后的产品列表，增加了 _span 属性
     */
    getProcessedShipmentData(shipments) {
      if (!shipments || shipments.length === 0) {
        return [];
      }

      // 1. 复制并按 SKU 排序 (重要！合并依赖于相同 SKU 的行相邻)
      // 使用 slice() 创建副本，避免修改原始数据
      const sortedShipments = shipments.slice().sort((a, b) => {
        if (a.sku < b.sku) return -1;
        if (a.sku > b.sku) return 1;
        return 0;
      });

      // 2. 计算合并信息
      let currentSpan = 0; // 当前 SKU 分组已计算的行数
      let firstRowIndex = 0; // 当前 SKU 分组第一行的索引

      sortedShipments.forEach((row, index) => {
        if (index === 0 || row.sku !== sortedShipments[index - 1].sku) {
          // 新的 SKU 分组开始
          // 将上一个分组的合并行数设置到其第一行
          if (index > 0) {
            sortedShipments[firstRowIndex]._span = currentSpan;
          }
          // 重置计数器和起始行索引
          currentSpan = 1;
          firstRowIndex = index;
          row._span = 1; // 默认为 1，如果它是分组的最后一行也是唯一一行
        } else {
          // SKU 与上一行相同，属于同一分组
          currentSpan++;
          row._span = 0; // 非首行，设置为 0，由首行负责合并
        }

        // 处理最后一行/最后一个分组
        if (index === sortedShipments.length - 1) {
          sortedShipments[firstRowIndex]._span = currentSpan;
        }
      });

      return sortedShipments;
    },

    /**
     * @description 子表格的合并单元格方法
     * @param {Object} param - 包含 { row, column, rowIndex, columnIndex }
     */
    childSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 需要合并的列的索引 (注意：索引从 0 开始)
      // 图片(1), 品名(2), SKU(3), 可用量(5)
      const mergeColumnIndices = [1, 2, 3, 5, 6];

      if (mergeColumnIndices.includes(columnIndex)) {
        // 从预处理数据中获取需要合并的行数 _span
        const rowspan = row._span || 0; // 如果没有 _span 属性或为 0，则不显示
        return {
          rowspan: rowspan,
          colspan: rowspan > 0 ? 1 : 0, // 如果 rowspan>0 正常显示，否则隐藏单元格
        };
      } else {
        // 其他列不合并
        return {
          rowspan: 1,
          colspan: 1,
        };
      }
    },

    /**
     * @description 子表格的合并单元格方法
     * @param {Object} param - 包含 { row, column, rowIndex, columnIndex }
     */
    subTableSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 需要合并的列的索引 (从 0 开始计数)
      // 图片(0), 品名(1), SKU(2), 价格(3)
      const mergeColumnIndices = [0, 1, 2, 3];

      if (mergeColumnIndices.includes(columnIndex)) {
        // 从预处理数据中获取需要合并的行数 _span
        // 如果 row._span 是 0 或 undefined，则 rowspan 为 0
        const rowspan = row._span || 0;
        return {
          rowspan: rowspan,
          colspan: rowspan > 0 ? 1 : 0, // rowspan > 0 时正常显示，否则隐藏单元格
        };
      } else {
        // 其他列不合并
        return {
          rowspan: 1,
          colspan: 1,
        };
      }
    },
    /** 处理点击物流公司单元格事件 */
    handleOpenLogisticsDialog(row) {
      const shippedOrLaterStatus = 1; // 发货状态
      if (row.status == shippedOrLaterStatus) {
        this.$message.warning("备货计划已发货，不能修改物流公司");
        return; // 停止执行
      }
      this.currentEditingStockPlan = { ...row };

      this.logisticsForm.selectedLogisticsId = row.companyId || null;

      this.updatelogisticsDialogVisible = true; // 打开弹窗
    },

    /** 重置弹窗表单状态 */
    resetLogisticsForm() {
      // 弹窗关闭时重置
      this.logisticsForm.selectedLogisticsId = null;
      this.currentEditingStockPlan = null;
      this.logisticsSubmitLoading = false; // 重置加载状态
    },

    /** 提交物流公司更改 */
    async submitLogisticsChange() {
      // 基础校验
      if (!this.logisticsForm.selectedLogisticsId) {
        this.$message.warning("请选择一个物流公司");
        return;
      }
      if (
        !this.currentEditingStockPlan ||
        !this.currentEditingStockPlan.stockId
      ) {
        this.$message.error("无法确定要修改的备货计划，请重试");
        return;
      }

      this.logisticsSubmitLoading = true; // 开始加载
      // 准备提交给后端的数据
      const payload = {
        stockId: this.currentEditingStockPlan.stockId, // 要更新的备货计划 ID
        logisticsCompany: this.logisticsForm.selectedLogisticsId, // 选中的新物流公司 ID
      };

      try {
        await updateStockPlanLogistics(payload);

        this.$message.success("物流公司修改成功");
        this.updatelogisticsDialogVisible = false; // 关闭弹窗
        this.getList(); // 刷新主表格数据以显示更改
      } catch (error) {
        console.error("修改物流公司失败:", error);
        this.$message.error("物流公司修改失败，请稍后重试");
      } finally {
        this.logisticsSubmitLoading = false; // 结束加载动画
      }
    },
    // 点击列打开弹窗
    handleOpenVolumeModeDialog(row) {
      // const shippedOrLaterStatus = 1; // 发货及之后均不可修改
      // if (row.status === shippedOrLaterStatus) {
      //   this.$message.warning("备货计划已发货，不能修改体积模式");
      //   return;
      // }
      this.currentEditingStockPlan = { ...row };
      this.volumeForm.selectedVolumeMode = row.volumeMode + "" || null;
      this.updateVolumeDialogVisible = true;
    },

    // 重置表单
    resetVolumeForm() {
      this.volumeForm.selectedVolumeMode = null;
      this.currentEditingStockPlan = null;
    },

    // 提交体积模式更改
    async submitVolumeModeChange() {
      if (!this.volumeForm.selectedVolumeMode) {
        this.$message.warning("请选择体积计算模式");
        return;
      }
      if (
        !this.currentEditingStockPlan ||
        !this.currentEditingStockPlan.stockId
      ) {
        this.$message.error("无法确定要修改的备货计划，请重试");
        return;
      }

      this.volumeSubmitLoading = true;
      const payload = {
        stockId: this.currentEditingStockPlan.stockId,
        volumeMode: this.volumeForm.selectedVolumeMode,
      };

      try {
        await updateStockPlanVolumeMode(payload);
        this.$message.success("体积模式修改成功");
        this.updateVolumeDialogVisible = false;
        this.getList(); // 刷新表格
      } catch (err) {
        console.error("修改体积模式失败:", err);
        this.$message.error("体积模式修改失败，请稍后重试");
      } finally {
        this.volumeSubmitLoading = false;
      }
    },
    /**
     * 输入金额之后自动计算对应的每个产品的运费
     */
    calculateFreight() {
      const totalAmount = parseFloat(this.totalAmount);
      if (isNaN(totalAmount) || totalAmount <= 0) {
        this.$message.error("请输入正确的总金额！");
        return;
      }

      const calculationMode = this.currentStockRow.volumeMode;
      const CALCULATION_SCALE = 10; // 添加计算精度常量

      // 如果表格数据为空，不进行处理
      if (this.tableData.length === 0) {
        this.$message.error("运费清单为空，不进行处理。");
        return;
      }

      // 辅助函数："尾数进一"到小数点后两位
      const ceilToTwoDecimals = (num) => Math.ceil(num * 100) / 100;

      // 解析尺寸和重量的函数
      const parseDimension = (dimStr) => {
        return parseFloat(dimStr.trim());
      };

      const parseWeightString = (weightStr) => {
        return parseFloat(weightStr.replace(/KG/i, "").trim());
      };

      // === 开始计算逻辑 ===

      // 步骤 1: 按 boxNumber 分组 SKU，并收集初始箱子属性
      const boxesMap = {};
      this.tableData.forEach((skuRow) => {
        if (!boxesMap[skuRow.boxNumber]) {
          boxesMap[skuRow.boxNumber] = {
            boxNumber: skuRow.boxNumber,
            boxSize: skuRow.boxSize,
            boxWeightStr: skuRow.boxWeight,
            skusInBox: [],
            physicalBoxChargeableMetric: 0,
            allocatedBoxFreight: 0,
            totalProductLevelChargeableInBox: 0,
          };
        }
        boxesMap[skuRow.boxNumber].skusInBox.push(skuRow);

        // 清除或初始化行项目上的运费字段
        this.$set(skuRow, "freight", null);
        this.$set(skuRow, "unitFreight", null);
      });

      let overallTotalChargeableMetric = 0;
      const KG_DIVISOR = 6000;
      const M3_DIVISOR = 1000000;
      const M3_WEIGHT_CONVERSION_FACTOR = 363;

      // 步骤 2: 计算每个物理箱的计费指标 (重量或体积)
      Object.values(boxesMap).forEach((boxData) => {
        const boxDimsStr = boxData.boxSize.split("*");
        const l = parseDimension(boxDimsStr[0]);
        const w = parseDimension(boxDimsStr[1]);
        const h = parseDimension(boxDimsStr[2]);
        const actualBoxWeightKg = parseWeightString(boxData.boxWeightStr);

        let physicalChargeable;
        if (calculationMode == 1) {
          // KG 模式
          const volumeWeight = (l * w * h) / KG_DIVISOR;
          physicalChargeable = ceilToTwoDecimals(
            Math.max(volumeWeight, actualBoxWeightKg)
          );
        } else if (calculationMode == 2) {
          // M³ 模式
          const calculatedVolumeM3 = ceilToTwoDecimals(
            (l * w * h) / M3_DIVISOR
          );
          const actualWeightEquivalentM3 = ceilToTwoDecimals(
            actualBoxWeightKg / M3_WEIGHT_CONVERSION_FACTOR
          );
          physicalChargeable = Math.max(
            calculatedVolumeM3,
            actualWeightEquivalentM3
          );
        } else {
          this.$message.error("未知的计算模式: " + calculationMode);
          return;
        }

        boxData.physicalBoxChargeableMetric = physicalChargeable;
        overallTotalChargeableMetric += physicalChargeable;
      });

      if (overallTotalChargeableMetric <= 0) {
        this.$message.error(
          "总计费重量/体积为0，无法分摊运费。所有运费将设置为0。"
        );
        this.tableData.forEach((row) => {
          this.$set(row, "freight", "0.00");
          this.$set(row, "unitFreight", "0.00");
        });
        return;
      }

      // 步骤 3: 将总运费分配给每个物理箱
      Object.values(boxesMap).forEach((boxData) => {
        const boxShareRatio =
          boxData.physicalBoxChargeableMetric / overallTotalChargeableMetric;
        const rawBoxFreight = totalAmount * boxShareRatio;

        if (calculationMode == 1) {
          // KG 模式 - 箱子运费向上舍入到4位小数
          boxData.allocatedBoxFreight =
            Math.ceil(rawBoxFreight * 10000) / 10000;
        } else if (calculationMode == 2) {
          // M³ 模式 - "尾数进一"到两位小数
          boxData.allocatedBoxFreight = ceilToTwoDecimals(rawBoxFreight);
        }
      });

      // 步骤 4 & 5: 计算产品级别的计费指标，并将箱子运费分配给箱内SKU
      Object.values(boxesMap).forEach((boxData) => {
        // 箱内第一遍循环: 计算产品级别的计费指标
        boxData.skusInBox.forEach((skuRow) => {
          const productDimsStr = skuRow.productSize.split("*");
          const pl = parseDimension(productDimsStr[0]);
          const pw = parseDimension(productDimsStr[1]);
          const ph = parseDimension(productDimsStr[2]);
          const productUnitWeightKg = parseWeightString(skuRow.productWeight);
          const quantity = parseInt(skuRow.quantity, 10) || 0;

          let productLevelTotalChargeableMetric;
          if (calculationMode == 1) {
            // KG 模式
            const productTotalVolumeWeight =
              (pl * pw * ph * quantity) / KG_DIVISOR;
            const productTotalActualWeight = productUnitWeightKg * quantity;
            productLevelTotalChargeableMetric = ceilToTwoDecimals(
              Math.max(productTotalVolumeWeight, productTotalActualWeight)
            );
          } else {
            // M³ 模式
            const productTotalVolumeM3 = ceilToTwoDecimals(
              (pl * pw * ph * quantity) / M3_DIVISOR
            );
            const productTotalActualWeightEquivalentM3 = ceilToTwoDecimals(
              (productUnitWeightKg * quantity) / M3_WEIGHT_CONVERSION_FACTOR
            );
            productLevelTotalChargeableMetric = Math.max(
              productTotalVolumeM3,
              productTotalActualWeightEquivalentM3
            );
          }

          skuRow.tempProductLevelChargeableMetric =
            productLevelTotalChargeableMetric;
          boxData.totalProductLevelChargeableInBox +=
            productLevelTotalChargeableMetric;
        });

        // 箱内第二遍循环: 将分配给箱子的运费分摊到SKU
        boxData.skusInBox.forEach((skuRow) => {
          let skuFreightPortion = 0;
          const tempProductMetric =
            skuRow.tempProductLevelChargeableMetric || 0;

          if (boxData.totalProductLevelChargeableInBox > 0) {
            // 使用更高精度计算比例，与后端保持一致
            const skuShareRatioInBox =
              tempProductMetric / boxData.totalProductLevelChargeableInBox;
            skuFreightPortion =
              boxData.allocatedBoxFreight * skuShareRatioInBox;
          } else if (
            boxData.skusInBox.length > 0 &&
            boxData.allocatedBoxFreight !== 0
          ) {
            skuFreightPortion =
              boxData.allocatedBoxFreight / boxData.skusInBox.length;
          }

          // 按照后端做法，对SKU行项目总运费进行"尾数进一"
          this.$set(
            skuRow,
            "freight",
            ceilToTwoDecimals(skuFreightPortion).toFixed(2)
          );

          let perUnitFreight = 0;
          if (parseInt(skuRow.quantity, 10) > 0) {
            // 使用精确的skuFreightPortion计算单位运费，然后"尾数进一"
            const preciseUnitFreight =
              skuFreightPortion / parseInt(skuRow.quantity, 10);
            perUnitFreight = ceilToTwoDecimals(preciseUnitFreight);
          }
          this.$set(skuRow, "unitFreight", perUnitFreight.toFixed(2));
        });
      });

      // 计算每个箱子的总运费并显示在第一个产品行
      const boxTotalFreights = {};
      const processedBoxes = new Set();

      // 先计算每个箱子的总运费
      this.tableData.forEach((row) => {
        if (row.boxNumber) {
          if (!boxTotalFreights[row.boxNumber]) {
            boxTotalFreights[row.boxNumber] = 0;
          }
          if (row.freight) {
            boxTotalFreights[row.boxNumber] += parseFloat(row.freight);
          }
        }
      });

      // 将总运费设置到每个箱子的对应行
      this.tableData.forEach((row) => {
        const boxNum = row.boxNumber;
        if (boxNum && !processedBoxes.has(boxNum)) {
          // 设置箱子总运费到第一个出现该箱号的行
          this.$set(row, "freight", boxTotalFreights[boxNum].toFixed(2));
          processedBoxes.add(boxNum);
        } else if (boxNum && processedBoxes.has(boxNum)) {
          // 对于同箱号的后续行，清除freight值（因为在UI上它们会被合并）
          this.$set(row, "freight", "");
        }
      });

      // 添加校验：确保单个运费×数量的总和 >= 原始总运费，且不超过原始总运费+2%
      let calculatedTotalFreight = 0;
      Object.values(boxTotalFreights).forEach((boxFreight) => {
        calculatedTotalFreight += boxFreight;
      });

      // 计算上界限制
      const upperLimit = totalAmount * 1.02;

      if (calculatedTotalFreight < totalAmount) {
        this.$message.error(
          `运费分摊异常：计算后总运费(${calculatedTotalFreight.toFixed(
            2
          )})小于原始总运费(${totalAmount.toFixed(2)})`
        );
      } else if (calculatedTotalFreight > upperLimit) {
        const excess = calculatedTotalFreight - upperLimit;
        const excessPercentage = ((excess * 100) / totalAmount).toFixed(2);

        this.$message.warning(
          `运费分摊超额：计算后总运费(${calculatedTotalFreight.toFixed(2)})` +
            `超过原始总运费(${totalAmount.toFixed(2)})的2%上限。` +
            `超出金额：${excess.toFixed(2)}元，` +
            `超出比例：${excessPercentage}%，` +
            `最大允许值：${upperLimit.toFixed(2)}元`
        );
      }
    },

    // 打开编辑快递单号对话框
    handleEditTrackingNumber(row) {
      this.trackingNumberForm = {
        stockId: row.stockId,
        stockNumber: row.stockNumber,
        companyName: row.companyName,
        trackingNumber: row.trackingNumber || "",
      };
      this.trackingNumberDialogVisible = true;
    },

    // 提交快递单号
    submitTrackingNumber() {
      if (!this.trackingNumberForm.trackingNumber) {
        this.$message.warning("请输入快递单号");
        return;
      }

      // 调用API更新快递单号
      updateStockTrackingNumber({
        stockId: this.trackingNumberForm.stockId,
        trackingNumber: this.trackingNumberForm.trackingNumber,
      }).then((response) => {
        this.$modal.msgSuccess("快递单号更新成功");
        this.trackingNumberDialogVisible = false;
        // 刷新列表数据
        this.getList();
      });
    },
  },
};
</script>
<style scoped>
.select-input {
  width: 120px;
}

/* 增加第二层展开箭头的右偏移 */
.el-table__expand-column .el-table__expand-icon {
  margin-left: 15px;
  /* 适当增加右移的距离 */
}

.positive {
  color: green;
}

.negative {
  color: red;
}

/* 将此代码添加到你组件的 <style scoped> 部分 */
.logistics-company-link {
  color: #409eff;
  /* Element UI 的主蓝色 */
  cursor: pointer;
  /* 鼠标悬停时显示手型光标 */
  text-decoration: none;
  /* 可选：移除下划线 */
}

.logistics-company-link:hover {
  text-decoration: underline;
  /* 可选：鼠标悬停时添加下划线 */
}

.volume-mode-link {
  color: #409eff;
  cursor: pointer;
}
</style>
